/*
 * All content copyright http://www.j2eefast.com, unless 
 * otherwise indicated. All rights reserved.
 * No deletion without permission
 */
package com.j2eefast.framework.config;

import cn.hutool.core.comparator.ComparableComparator;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.setting.Setting;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.bstek.ureport.console.ServletAction;
import com.j2eefast.common.core.constants.ConfigConstant;
import com.j2eefast.common.core.io.PropertiesUtils;
import com.j2eefast.common.core.utils.RedisUtil;
import com.j2eefast.common.core.utils.SpringUtil;
import com.j2eefast.common.core.utils.ToolUtil;
import com.j2eefast.common.db.context.DataSourceContext;
import com.j2eefast.common.db.utils.SqlExe;
import com.j2eefast.framework.quartz.entity.SysJobEntity;
import com.j2eefast.framework.quartz.service.SysJobService;
import com.j2eefast.framework.quartz.utils.ScheduleUtils;
import com.j2eefast.framework.sys.entity.SysMenuEntity;
import com.j2eefast.framework.sys.entity.SysModuleEntity;
import com.j2eefast.framework.sys.service.SysMenuService;
import com.j2eefast.framework.sys.service.SysModuleService;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.C;
import org.quartz.CronExpression;
import org.quartz.Scheduler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.Date;
import java.util.List;

/**
 *
 * @ClassName: BaseInitialze
 * @Package: com.j2eefast.framework.config
 * @author: zhouzhou Emall:loveingowp@163.com
 * @time 2020/2/14 18:32
 * @version V1.0
 */
@Slf4j
@Component
public class BaseInitialze  implements ApplicationRunner {


    @Autowired
    private SysMenuService sysMenuService;
	@Qualifier("schedulerFactoryBean")
	@Autowired
	private Scheduler scheduler;
    @Autowired
    private SysJobService sysJobService;
    @Autowired
    private RedisUtil redisUtil;
    // 语言切换
    @Value("#{ @environment['fast.messages.enabled'] ?: false }")
    private boolean msgEnabled;


    @Value("#{ @environment['fast.ureport.enabled'] ?: false }")
    private boolean enabled;


    @SuppressWarnings({ "unchecked"})
	@Override
    public void run(ApplicationArguments args) throws Exception {

        //清除
		scheduler.clear();

        //设置系统版本号
        redisUtil.set(ConfigConstant.CONFIG_KEY, PropertiesUtils.getInstance().getProperty(ConfigConstant.SYS_VERSION,
                "1.0.1"),RedisUtil.NOT_EXPIRE);
        /**
         * 检测定时任务
         */
        List<SysJobEntity> sysJobList =  sysJobService.list();
        if(ToolUtil.isNotEmpty(sysJobList)) {
        	for(SysJobEntity sysJob: sysJobList) {
        	    if(isOnlyOnce(sysJob.getCronExpression())){
                    continue;
                }
        	    if(!ScheduleUtils.checkExists(scheduler,sysJob)){
        	        log.info("---系统没有任务需创建:{}--",sysJob.getJobName() + "("+sysJob.getId()+")");
                    ScheduleUtils.createScheduleJob(scheduler, sysJob);
                }else {
                    log.info("---系统有任务需更新:{}--",sysJob.getJobName() + "("+sysJob.getId()+")");
                    ScheduleUtils.updateScheduleJob(scheduler,sysJob);
                }
        	}
        }


        if(msgEnabled){
            if(sysMenuService.count(new QueryWrapper<SysMenuEntity>().eq("id",1447910714162241537L)
                    .eq("hide","1")) > 0){
                sysMenuService.update(new UpdateWrapper<SysMenuEntity>()
                        .eq("id",1447910714162241537L).eq("hide","1").set("hide","0"));
                sysMenuService.clearMenuRedis();
            }
        }else{
            if(sysMenuService.count(new QueryWrapper<SysMenuEntity>().eq("id",1447910714162241537L)
                    .eq("hide","0")) > 0){
                sysMenuService.update(new UpdateWrapper<SysMenuEntity>()
                        .eq("id",1447910714162241537L).eq("hide","0").set("hide","1"));
                sysMenuService.clearMenuRedis();
            }
        }


        /**
         * 检测是否加载ureport2 报表
         */
        if(enabled){
            //卸载系统自带
            SpringUtil.unregisterBean("ureport.exportExcelServletAction");
            SpringUtil.unregisterBean("ureport.datasourceServletAction");
            SpringUtil.unregisterBean("ureport.htmlPreviewServletAction");
            SpringUtil.unregisterBean("ureport.designerServletAction");
            if(sysMenuService.count(new QueryWrapper<SysMenuEntity>().eq("id",108)
                    .eq("hide","1")) > 0){
                sysMenuService.update(new UpdateWrapper<SysMenuEntity>()
                        .eq("id",108).eq("hide","1").set("hide","0"));
                sysMenuService.clearMenuRedis();
            }
        }else{
            if(sysMenuService.count(new QueryWrapper<SysMenuEntity>().eq("id",108)
                    .eq("hide","0")) > 0){
                sysMenuService.update(new UpdateWrapper<SysMenuEntity>()
                        .eq("id",108).eq("hide","0").set("hide","1"));
                sysMenuService.clearMenuRedis();
            }
        }
    }

    public boolean isOnlyOnce(String cron){
        try{
            CronExpression cronExpression = new CronExpression(cron);
            Date nextDate = cronExpression.getNextInvalidTimeAfter(new Date());
            Date expressionDate = cronExpression.getNextValidTimeAfter(nextDate);
            return expressionDate == null;
        }catch (Exception e){
            return false;
        }
    }


    public File getResourceFile(Resource resource) throws IOException {
        File file  = FileUtil.createTempFile(".tmp",true);
        InputStream inputStream = resource.getInputStream();
        OutputStream outputStream = new FileOutputStream(file);
        byte[] buffer = new byte[1024];
        int bytesRead;
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, bytesRead);
        }
        inputStream.close();
        outputStream.close();
        return file;
    }
}
